home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / ODF / OS / FWGraphx / PRPictur.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  14.5 KB  |  573 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRPictur.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef SLPALETE_H
  13. #include "SLPalete.h"
  14. #endif
  15.  
  16. #ifndef FWODEXCE_H
  17. #include "FWODExce.h"
  18. #endif
  19.  
  20. #ifndef FWBITMAP_H
  21. #include "FWBitmap.h"
  22. #endif
  23.  
  24. #ifndef FWWINRES_H
  25. #include "FWWinRes.h"
  26. #endif
  27.  
  28. #ifndef FWSTRMRW_H
  29. #include "FWStrmRW.h"
  30. #endif
  31.  
  32. #ifndef FWRESOUR_H
  33. #include "FWResour.h"
  34. #endif
  35.  
  36. #ifndef FWGC_H
  37. #include "FWGC.h"
  38. #endif
  39.  
  40. #ifndef PRGDEV_H
  41. #include "PRGDev.h"
  42. #endif
  43.  
  44. #ifndef FWSOMENV_H
  45. #include "FWSOMEnv.h"
  46. #endif
  47.  
  48. #ifndef PRPICTUR_H
  49. #include "PRPictur.h"
  50. #endif
  51.  
  52. #ifndef FWMEMMGR_H
  53. #include "FWMemMgr.h"
  54. #endif
  55.  
  56. #ifndef FWEXCEPT_H
  57. #include "FWExcept.h"
  58. #endif
  59.  
  60. #ifndef SOM_FW_OResourceFile_xh
  61. #include "SLResFil.xh"
  62. #endif
  63.  
  64. // ----- Macintosh Includes -----
  65.  
  66. #if defined(FW_BUILD_MAC) && !defined(__PICTUTILS__)
  67. #include <PictUtils.h>
  68. #endif
  69.  
  70. //========================================================================================
  71. //    RunTime Info
  72. //========================================================================================
  73.  
  74. #ifdef FW_BUILD_MAC
  75. #pragma segment FWGraphics_Picture
  76. #endif
  77.  
  78. FW_DEFINE_AUTO(FW_CPrivPictureRep)
  79.  
  80. //----------------------------------------------------------------------------------------
  81. //    Placeable (Aldus) metafile definitions for Windows
  82. //----------------------------------------------------------------------------------------
  83.  
  84. #ifdef FW_BUILD_WIN
  85.  
  86. #pragma pack(push,1)
  87.  
  88. struct RECT16
  89. {
  90.     short   left;
  91.     short   top;
  92.     short   right;
  93.     short   bottom;
  94. };
  95.  
  96. struct SAldusHeader
  97. {
  98.     DWORD   key;
  99.     WORD    hmf;
  100.     RECT16    bbox;
  101.     WORD    inch;
  102.     DWORD   reserved;
  103.     WORD    checksum;
  104. } ;
  105.  
  106. #pragma pack(pop)
  107.  
  108. const DWORD kAldusKey =    0x9AC6CDD7l;
  109.  
  110. #endif
  111.  
  112. //----------------------------------------------------------------------------------------
  113. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  114. //----------------------------------------------------------------------------------------
  115. //    From Stream: we own the picture
  116.  
  117. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_CReadableStream& stream) :
  118.     fOwnPicture(TRUE),
  119.     fPlatformPict(NULL)
  120. {
  121. #ifdef FW_BUILD_MAC
  122.     fMacLockCount    = 0;
  123. #endif
  124.  
  125.     PrivReadFrom(stream);
  126.     
  127.     FW_END_CONSTRUCTOR
  128. }
  129.  
  130. //----------------------------------------------------------------------------------------
  131. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  132. //----------------------------------------------------------------------------------------
  133. //    From File: we own the picture
  134.  
  135. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_OResourceFile* resourceFile, FW_ResourceID resID) :
  136.     fOwnPicture(TRUE),
  137.     fPlatformPict(NULL)
  138. {
  139.     FW_SOMEnvironment ev;
  140.  
  141. #ifdef FW_BUILD_MAC
  142. FW_UNUSED(resourceFile);
  143.  
  144.     fMacLockCount = 0;
  145.  
  146.     FW_PlatformPict newPict = (FW_PlatformPict) resourceFile->PrivGetSpecialResource(ev, resID, FW_kPicture);
  147.     
  148.     if (newPict == NULL)
  149.     {
  150.         FW_FailOnEvError(ev);
  151.     }
  152.  
  153.     // Because of CFM we have to detach the resource
  154.     ::DetachResource((Handle)newPict);    
  155.     FW_ASSERT(ResError() == noErr);
  156.  
  157.     // resource may have been purgeable
  158.     ::HNoPurge((Handle)newPict);
  159.  
  160.     AdoptPlatformPict(newPict);
  161. #endif
  162.  
  163. #ifdef FW_BUILD_WIN
  164.     FW_PResource resource(ev, resourceFile, resID, FW_kPicture);
  165.     FW_PResourceSink sink(ev, resource);
  166.     FW_CReadableStream stream(sink);
  167.     PrivReadFrom(stream);
  168. #endif
  169.  
  170.     FW_END_CONSTRUCTOR
  171. }
  172.  
  173. //----------------------------------------------------------------------------------------
  174. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  175. //----------------------------------------------------------------------------------------
  176. //    From platform pict: we don't own the picture.
  177.  
  178. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_PlatformPict platformPict) :
  179.     fOwnPicture(false),
  180.     fPlatformPict(platformPict)
  181. {
  182.     FW_ASSERT(platformPict != NULL);
  183.     
  184. #ifdef FW_BUILD_MAC
  185.     fMacLockCount    = 0;
  186. #endif
  187.     FW_END_CONSTRUCTOR
  188. }
  189.  
  190. //----------------------------------------------------------------------------------------
  191. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  192. //----------------------------------------------------------------------------------------
  193. //    From another Pict: we own the picture (a copy is made)
  194.  
  195. FW_CPrivPictureRep::FW_CPrivPictureRep(const FW_CPrivPictureRep& other) :
  196.     fOwnPicture(TRUE),
  197.     fPlatformPict(NULL)
  198. {
  199.     FW_PlatformPict otherPict = other.GetPlatformPict();
  200.     
  201. #ifdef FW_BUILD_MAC
  202.     fPlatformPict = (FW_PlatformPict) FW_CMemoryManager::CopySystemHandle((FW_PlatformHandle)otherPict);
  203.     fMacLockCount    = 0;
  204. #endif
  205. #ifdef FW_BUILD_WIN
  206.     fPlatformPict = ::CopyEnhMetaFile(otherPict, NULL);
  207. #endif
  208.     
  209.     if (fPlatformPict == 0)
  210.         FW_Failure(FW_xMemoryExhausted);
  211.  
  212.     FW_END_CONSTRUCTOR
  213. }
  214.  
  215. //----------------------------------------------------------------------------------------
  216. //    FW_CPrivPictureRep::~FW_CPrivPictureRep
  217. //----------------------------------------------------------------------------------------
  218.  
  219. FW_CPrivPictureRep::~FW_CPrivPictureRep()
  220. {
  221.     FW_START_DESTRUCTOR
  222.      PrivDisposePict();
  223. }
  224.  
  225. //----------------------------------------------------------------------------------------
  226. //    FW_CPrivPictureRep::Write
  227. //----------------------------------------------------------------------------------------
  228.  
  229. void FW_CPrivPictureRep::Write(FW_CWritableStream& stream)
  230. {
  231. #ifdef FW_BUILD_MAC
  232.     unsigned long picSize = FW_CMemoryManager::GetSystemHandleSize((FW_PlatformHandle)fPlatformPict);
  233.     stream << picSize;
  234.  
  235.     MacLock();
  236.     
  237.     FW_TRY
  238.     {
  239.         stream.Write(*fPlatformPict, picSize);
  240.     }
  241.     FW_CATCH_BEGIN
  242.     FW_CATCH_EVERYTHING()
  243.     {
  244.         MacUnlock();
  245.         FW_THROW_SAME();
  246.     }
  247.     FW_CATCH_END
  248.  
  249.     MacUnlock();    
  250. #endif    
  251. #ifdef FW_BUILD_WIN
  252.     UINT bitsSize = ::GetEnhMetaFileBits(fPlatformPict, 0, NULL);
  253.  
  254.     BYTE* bitsBuf = new BYTE[bitsSize];
  255.     ::GetEnhMetaFileBits(fPlatformPict, bitsSize, bitsBuf);
  256.     
  257.     FW_TRY
  258.     {
  259.         stream.Write(bitsBuf, bitsSize);
  260.     }
  261.     FW_CATCH_BEGIN
  262.     FW_CATCH_EVERYTHING()
  263.     {
  264.         delete[] bitsBuf;
  265.         FW_THROW_SAME();
  266.     }
  267.     FW_CATCH_END
  268.  
  269.     delete[] bitsBuf;
  270. #endif
  271. }
  272.  
  273. //----------------------------------------------------------------------------------------
  274. //    FW_CPrivPictureRep::IsEqual
  275. //----------------------------------------------------------------------------------------
  276.  
  277. FW_Boolean FW_CPrivPictureRep::IsEqual(const FW_CPrivPictureRep& other) const
  278. {
  279.     return fPlatformPict == other.fPlatformPict;
  280. }
  281.  
  282. //----------------------------------------------------------------------------------------
  283. //    FW_CPrivPictureRep::GetPictBounds
  284. //----------------------------------------------------------------------------------------
  285.  
  286. void FW_CPrivPictureRep::GetPictBounds(FW_SRect& bounds) const
  287. {
  288. #ifdef FW_BUILD_MAC
  289.  
  290.     PictInfo pictInfo;
  291.  
  292.     if(::GetPictInfo(fPlatformPict, &pictInfo, 0, 0, 0, 0) != noErr)
  293.     {
  294.         pictInfo.sourceRect = (*fPlatformPict)->picFrame;
  295.     }
  296.  
  297.     bounds.left        = FW_kFixed0;
  298.     bounds.top        = FW_kFixed0;
  299.     bounds.right    = FW_IntToFixed(pictInfo.sourceRect.right - pictInfo.sourceRect.left);
  300.     bounds.bottom    = FW_IntToFixed(pictInfo.sourceRect.bottom - pictInfo.sourceRect.top);
  301.  
  302. #endif
  303.  
  304. #ifdef FW_BUILD_WIN
  305.     ENHMETAHEADER emh;
  306.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  307.     
  308.     // emh.rclBounds is the bounding rectangle in pixels, computed by GDI
  309.  
  310.     bounds.left        = FW_IntToFixed((int) emh.rclBounds.left);
  311.     bounds.top        = FW_IntToFixed((int) emh.rclBounds.top);
  312.     bounds.right    = FW_IntToFixed((int) emh.rclBounds.right);
  313.     bounds.bottom    = FW_IntToFixed((int) emh.rclBounds.bottom);
  314. #endif
  315. }
  316.  
  317. //----------------------------------------------------------------------------------------
  318. //    FW_CPrivPictureRep::GetPictBoundsGC
  319. //----------------------------------------------------------------------------------------
  320.  
  321. void FW_CPrivPictureRep::GetPictBoundsGC(Environment* ev, FW_SGraphicContext& gc, FW_SRect& bounds) const
  322. {    
  323. #ifdef FW_BUILD_MAC
  324.     FW_SPoint size;
  325.     
  326.     FW_SRect pictureBounds;
  327.     GetPictBounds(pictureBounds);
  328.     const long width = FW_FixedToInt(pictureBounds.right - pictureBounds.left);
  329.     const long height = FW_FixedToInt(pictureBounds.bottom - pictureBounds.top);
  330.     
  331.     FW_PrivGC_DeviceToLogicalSize(ev, gc, width, height, size);
  332.     
  333.     // Let go if error    
  334.     bounds.left        =    FW_kFixed0;
  335.     bounds.top        =     FW_kFixed0;
  336.     bounds.right    =     size.x;
  337.     bounds.bottom    =    size.y;
  338. #endif
  339.  
  340. #ifdef FW_BUILD_WIN
  341.     ENHMETAHEADER emh;
  342.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  343.  
  344.     // emh.rclFrame is the bounding rectangle as specified by the creator, in 0.01 mm units
  345.  
  346.     HDC hDC = gc.fGraphicDevice->GetPlatformCanvas()->GetDC(ev);
  347.  
  348.     int xRes = ::GetDeviceCaps(hDC, LOGPIXELSX);
  349.     int yRes = ::GetDeviceCaps(hDC, LOGPIXELSY);
  350.  
  351.     FW_CPlatformRect plfmBounds;
  352.  
  353.     plfmBounds.left        = emh.rclFrame.left        * xRes / 2540;
  354.     plfmBounds.top        = emh.rclFrame.top        * yRes / 2540;
  355.     plfmBounds.right    = emh.rclFrame.right    * xRes / 2540;
  356.     plfmBounds.bottom    = emh.rclFrame.bottom    * yRes / 2540;
  357.  
  358.     FW_PrivGC_DeviceToLogicalRect(ev, gc, plfmBounds, bounds);
  359.     // Let go if error    
  360. #endif
  361. }
  362.  
  363. //----------------------------------------------------------------------------------------
  364. //    FW_CPrivPictureRep::GetPlatformPict
  365. //----------------------------------------------------------------------------------------
  366.  
  367. FW_PlatformPict    FW_CPrivPictureRep::GetPlatformPict() const
  368. {
  369.     return fPlatformPict;
  370. }
  371.  
  372. //----------------------------------------------------------------------------------------
  373. //    FW_CPrivPictureRep::IsPlatformPictOrphan
  374. //----------------------------------------------------------------------------------------
  375.  
  376. FW_Boolean FW_CPrivPictureRep::IsPlatformPictOrphan() const
  377. {
  378.     return !fOwnPicture;
  379. }
  380.  
  381. //----------------------------------------------------------------------------------------
  382. //    FW_CPrivPictureRep::OrphanPlatformPict
  383. //----------------------------------------------------------------------------------------
  384.  
  385. FW_PlatformPict    FW_CPrivPictureRep::OrphanPlatformPict()
  386. {
  387.     FW_ASSERT(fOwnPicture);        // Cannot orphan twice
  388.     fOwnPicture = FALSE;
  389.     return fPlatformPict;
  390. }
  391.  
  392. //----------------------------------------------------------------------------------------
  393. //    FW_CPrivPictureRep::SetPlatformPict
  394. //----------------------------------------------------------------------------------------
  395.  
  396. void FW_CPrivPictureRep::SetPlatformPict(FW_PlatformPict newPict)
  397. {
  398.     if (fPlatformPict != newPict)
  399.     {
  400.         PrivDisposePict();
  401.         fPlatformPict = newPict;
  402.     }
  403.     
  404.     fOwnPicture = FALSE;
  405. }
  406.  
  407. //----------------------------------------------------------------------------------------
  408. //    FW_CPrivPictureRep::AdoptPlatformPict
  409. //----------------------------------------------------------------------------------------
  410.  
  411. void FW_CPrivPictureRep::AdoptPlatformPict(FW_PlatformPict newPict)
  412. {
  413.     SetPlatformPict(newPict);
  414.     fOwnPicture = TRUE;
  415. }
  416.  
  417. #ifdef FW_BUILD_MAC
  418. //----------------------------------------------------------------------------------------
  419. //    FW_CPrivPictureRep::MacLock
  420. //----------------------------------------------------------------------------------------
  421.  
  422. void FW_CPrivPictureRep::MacLock()
  423. {
  424.     FW_ASSERT(fPlatformPict != NULL);
  425.  
  426.     if (++ fMacLockCount == 1)
  427.         FW_CMemoryManager::LockSystemHandle((FW_PlatformHandle)fPlatformPict);
  428. }
  429. #endif
  430.  
  431. #ifdef FW_BUILD_MAC
  432. //----------------------------------------------------------------------------------------
  433. //    FW_CPrivPictureRep::MacUnlock
  434. //----------------------------------------------------------------------------------------
  435.  
  436. void FW_CPrivPictureRep::MacUnlock()
  437. {
  438.     if (-- fMacLockCount == 0)
  439.         FW_CMemoryManager::UnlockSystemHandle((FW_PlatformHandle)fPlatformPict);    
  440. }
  441. #endif
  442.  
  443. //----------------------------------------------------------------------------------------
  444. //    FW_CPrivPictureRep::PrivReadFrom
  445. //----------------------------------------------------------------------------------------
  446.  
  447. void FW_CPrivPictureRep::PrivReadFrom(FW_CReadableStream& stream)
  448. {
  449. #ifdef FW_BUILD_MAC
  450.     unsigned long picSize;
  451.     stream >> picSize;
  452.     
  453.     fPlatformPict = (FW_PlatformPict) FW_CMemoryManager::AllocateSystemHandle(picSize);
  454.             
  455.     MacLock();
  456.     
  457.     FW_TRY
  458.     {
  459.         stream.Read(*fPlatformPict, picSize);
  460.     }
  461.     FW_CATCH_BEGIN
  462.     FW_CATCH_EVERYTHING()
  463.     {
  464.         MacUnlock();
  465.         ::DisposeHandle((Handle)fPlatformPict);
  466.         fPlatformPict = NULL;
  467.         FW_THROW_SAME();
  468.     }
  469.     FW_CATCH_END
  470.  
  471.     MacUnlock();
  472. #endif
  473. #ifdef FW_BUILD_WIN
  474.     HENHMETAFILE metafile = NULL;
  475.  
  476.     // Check if there is an Aldus metafile header
  477.     SAldusHeader aldusHeader;
  478.     stream.Read(&aldusHeader, sizeof(aldusHeader));
  479.     if(aldusHeader.key == kAldusKey)
  480.     {
  481.         // ----- This is an Aldus format metafile
  482.  
  483.         // Read the header
  484.         METAHEADER mfHeader;
  485.         stream.Read(&mfHeader, sizeof(mfHeader));
  486.  
  487.         // Read the bits
  488.         size_t bitsSize = mfHeader.mtSize * 2L;
  489.         BYTE* bitsBuf = new BYTE[bitsSize];
  490.         
  491.         FW_TRY
  492.         {
  493.             FW_CMemoryManager::CopyMemory(&mfHeader, bitsBuf, sizeof(mfHeader));
  494.             stream.Read(bitsBuf + sizeof(mfHeader), bitsSize - sizeof(mfHeader));
  495.         }
  496.         FW_CATCH_BEGIN
  497.         FW_CATCH_EVERYTHING()
  498.         {
  499.             delete[] bitsBuf;
  500.             FW_THROW_SAME();
  501.         }
  502.         FW_CATCH_END
  503.  
  504.         // Convert an Aldus (Win16) metafile to a Win32 Enhanced Metafile
  505.         METAFILEPICT mfPict;
  506.         mfPict.mm = MM_ANISOTROPIC;
  507.         mfPict.xExt = (aldusHeader.bbox.right - aldusHeader.bbox.left) * 2540 / aldusHeader.inch;
  508.         mfPict.yExt = (aldusHeader.bbox.bottom - aldusHeader.bbox.top) * 2540 / aldusHeader.inch;
  509.  
  510.         metafile = ::SetWinMetaFileBits(bitsSize, bitsBuf, NULL, &mfPict);
  511.         delete[] bitsBuf;
  512.     }
  513.     else
  514.     {
  515.         // ----- Not an Aldus metafile, try Win32 Enhanced metafile
  516.  
  517.         // Read the header
  518.         ENHMETAHEADER enhHeader;
  519.         FW_CMemoryManager::CopyMemory(&aldusHeader, &enhHeader, sizeof(aldusHeader));
  520.         stream.Read((char*) &enhHeader + sizeof(aldusHeader), sizeof(enhHeader) - sizeof(aldusHeader));
  521.  
  522.         // Verify the header
  523.         if(enhHeader.iType == EMR_HEADER || enhHeader.nSize == sizeof(enhHeader))
  524.         {
  525.             // Read the bits
  526.             size_t bitsSize = enhHeader.nBytes;
  527.             BYTE* bitsBuf = new BYTE[bitsSize];
  528.             FW_TRY
  529.             {
  530.                 FW_CMemoryManager::CopyMemory(&enhHeader, bitsBuf, sizeof(enhHeader));
  531.                 stream.Read(bitsBuf + sizeof(enhHeader), bitsSize - sizeof(enhHeader));
  532.             }
  533.             FW_CATCH_BEGIN
  534.             FW_CATCH_EVERYTHING()
  535.             {
  536.                 delete[] bitsBuf;
  537.                 FW_THROW_SAME();
  538.             }
  539.             FW_CATCH_END
  540.     
  541.             // Create a metafile and set the bits
  542.              metafile = ::SetEnhMetaFileBits(bitsSize, bitsBuf);
  543.             delete[] bitsBuf;
  544.         }
  545.     }
  546.  
  547.     if(metafile == NULL)
  548.         FW_Failure(FW_xInvalidPictureData);
  549.  
  550.     // Save metafile info
  551.     AdoptPlatformPict(metafile);
  552. #endif
  553. }
  554.  
  555. //----------------------------------------------------------------------------------------
  556. //    FW_CPrivPictureRep::PrivDisposePict
  557. //----------------------------------------------------------------------------------------
  558.  
  559. void FW_CPrivPictureRep::PrivDisposePict()
  560. {
  561.     if (fOwnPicture && fPlatformPict != NULL)
  562.     {
  563. #ifdef FW_BUILD_MAC
  564.         ::KillPicture(fPlatformPict);
  565. #endif
  566. #ifdef FW_BUILD_WIN
  567.         ::DeleteEnhMetaFile(fPlatformPict);
  568. #endif
  569.     }
  570.  
  571.     fPlatformPict = NULL;
  572. }
  573.